package com.extweb4j.core.controller;

import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;

import com.extweb4j.core.bean.Msg;
import com.extweb4j.core.kit.ExtKit;
import com.jfinal.core.Controller;
import com.jfinal.kit.PropKit;
import com.jfinal.plugin.activerecord.Model;
import com.jfinal.plugin.activerecord.Table;
import com.jfinal.plugin.activerecord.TableMapping;
import com.jfinal.upload.UploadFile;

/**
 * Ext框架Controller
 * 
 * @author: 周高军 2016年5月21日
 */
public abstract class ExtController extends Controller {

	private final static int timeStampLen = "2011-01-18 16:18:18".length();
	private final static String timeStampPattern = "yyyy-MM-dd HH:mm:ss";
	private final static String datePattern = "yyyy-MM-dd";

	public final static Logger LOG = Logger.getLogger(ExtController.class);

	protected void success() {
		renderJson(new Msg(true));
	}

	protected void success(String msg) {
		renderJson(new Msg(true, msg));
	}

	protected void error(String msg) {
		renderJson(new Msg(false, msg));
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	public <T> T getExtModel(Class<T> modelClass) {
		// TODO Auto-generated method stub
		Model model = null;
		try {
			model = (Model) modelClass.newInstance();

		} catch (InstantiationException | IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		Table table = TableMapping.me().getTable(model.getClass());
		Map<String, String[]> parasMap = getRequest().getParameterMap();
		for (Entry<String, String[]> e : parasMap.entrySet()) {
			String paraKey = e.getKey();
			String paraName = paraKey;
			Class colType = table.getColumnType(paraName);

			if (colType == null) {
				continue;
				// throw new ActiveRecordException("The model attribute " +
				// paraKey + " is not exists.");
			}
			String[] paraValue = e.getValue();
			try {
				// Object value = Converter.convert(colType, paraValue != null ?
				// paraValue[0] : null);
				Object value = paraValue[0] != null ? convert(colType,
						paraValue[0]) : null;
				model.set(paraName, value);
			} catch (Exception ex) {
				throw new RuntimeException("Can not convert parameter: "
						+ paraName, ex);
			}
		}
		return (T) model;
	}

	private Object convert(Class<?> clazz, String s) throws ParseException {

		if (clazz == String.class) {
			return ("".equals(s) ? null : s); // 用户在表单域中没有输入内容时将提交过来 "",
												// 因为没有输入,所以要转成 null.
		}
		s = s.trim();
		if ("".equals(s)) { // 前面的 String跳过以后,所有的空字符串全都转成 null, 这是合理的
			return null;
		}
		// 以上两种情况无需转换,直接返回, 注意, 本方法不接受null为 s 参数(经测试永远不可能传来null, 因为无输入传来的也是"")

		Object result = null;
		// mysql type: int, integer, tinyint(n) n > 1, smallint, mediumint
		if (clazz == Integer.class || clazz == int.class) {
			result = Integer.parseInt(s);
		}
		// mysql type: bigint
		else if (clazz == Long.class || clazz == long.class) {
			result = Long.parseLong(s);
		}
		// 经测试java.util.Data类型不会返回, java.sql.Date,
		// java.sql.Time,java.sql.Timestamp 全部直接继承自 java.util.Data, 所以
		// getDate可以返回这三类数据
		else if (clazz == java.util.Date.class) {
			if (s.length() >= timeStampLen) { // if (x < timeStampLen) 改用
												// datePattern 转换，更智能
				// Timestamp format must be yyyy-mm-dd hh:mm:ss[.fffffffff]
				// result = new
				// java.util.Date(java.sql.Timestamp.valueOf(s).getTime()); //
				// error under jdk 64bit(maybe)
				result = new SimpleDateFormat(timeStampPattern).parse(s);
			} else {
				// result = new
				// java.util.Date(java.sql.Date.valueOf(s).getTime()); // error
				// under jdk 64bit
				result = new SimpleDateFormat(datePattern).parse(s);
			}
		}
		// mysql type: date, year
		else if (clazz == java.sql.Date.class) {
			if (s.length() >= timeStampLen) { // if (x < timeStampLen) 改用
												// datePattern 转换，更智能
				// result = new
				// java.sql.Date(java.sql.Timestamp.valueOf(s).getTime()); //
				// error under jdk 64bit(maybe)
				result = new java.sql.Date(new SimpleDateFormat(
						timeStampPattern).parse(s).getTime());
			} else {
				// result = new
				// java.sql.Date(java.sql.Date.valueOf(s).getTime()); // error
				// under jdk 64bit
				result = new java.sql.Date(new SimpleDateFormat(datePattern)
						.parse(s).getTime());
			}
		}
		// mysql type: time
		else if (clazz == java.sql.Time.class) {
			result = java.sql.Time.valueOf(s);
		}
		// mysql type: timestamp, datetime
		else if (clazz == java.sql.Timestamp.class) {
			result = java.sql.Timestamp.valueOf(s);
		}
		// mysql type: real, double
		else if (clazz == Double.class) {
			result = Double.parseDouble(s);
		}
		// mysql type: float
		else if (clazz == Float.class) {
			result = Float.parseFloat(s);
		}
		// mysql type: bit, tinyint(1)
		else if (clazz == Boolean.class) {
			result = Boolean.parseBoolean(s) || "1".equals(s);
		}
		// mysql type: decimal, numeric
		else if (clazz == java.math.BigDecimal.class) {
			result = new java.math.BigDecimal(s);
		}
		// mysql type: unsigned bigint
		else if (clazz == java.math.BigInteger.class) {
			result = new java.math.BigInteger(s);
		}
		// mysql type: binary, varbinary, tinyblob, blob, mediumblob, longblob.
		// I have not finished the test.
		else if (clazz == byte[].class) {
			result = s.getBytes();
		} else {

			throw new RuntimeException(
					clazz.getName()
							+ " can not be converted, please use other type of attributes in your model!");
		}

		return result;
	}
	 /**
	  * Ext 上传文件
	  */
	 protected String extUploadFile(UploadFile uploadFile){
		 
		try {
			
			if(uploadFile.getFile().length() > (1024 * 1024 * 20)){
				throw new RuntimeException("上传文件大小不能超过10Mb!");
			}
			String path = PropKit.get("uploadFile");
			String webAddr = PropKit.get("webAddr");
			String backupFileDir = PropKit.get("backupFileDir");
			
			String fileName = ExtKit.renameFile(uploadFile.getFileName());
			//保存文件
			FileUtils.copyFile(uploadFile.getFile(),new File(path+fileName));
			LOG.debug("上传文件成功,"+backupFileDir + fileName);
			//备份
			FileUtils.copyFile(uploadFile.getFile(),new File(backupFileDir + fileName));
			LOG.debug("备份文件成功,"+backupFileDir + fileName);
			
			String fileUrl = webAddr + fileName.replaceAll("\\\\","/");
			
			return fileUrl;
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			throw new RuntimeException("上传出错!");
		}
		
	}
}
